package com.jushu.storbox.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Random;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.RemoteViews;

import com.jushu.storbox.FileDownloadActivity;
import com.jushu.storbox.R;
import com.jushu.storbox.constant.ClientConfig;
import com.jushu.storbox.entities.FileFolderInfo;

public class MusicService extends AbstractBaseService implements IMusicService {
	private MediaPlayer player;
	private boolean isPlaying;
	private boolean isFinish;
	private String currentPath;
	private int duration;
	private int currentDuration = 0;
	private NotificationManager manager;
	private Notification mNotification;
	private Thread notificationThread;
	private boolean isLoop = true;
	private Handler handler;
	private Context context;
	private RemoteViews notificationView;
	private int notificationId = new Random().nextInt(100);
	private int state = 0;
	private FileFolderInfo fileinfo;
	private FileInputStream fis;
	
	public MusicService() {
		handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				switch (msg.what) {
				case 1:
//					Log.i("liang", "handler 1");
					notificationView.setTextViewText(R.id.mdmview_notification_musicTime, formatData(getProgress())
							+ "/" + formatData(duration));
					notificationView.setProgressBar(R.id.mdmview_notification_musicProgress, 100, getProgress() * 100
							/ duration, false);
//					mNotification.flags = Notification.FLAG_ONGOING_EVENT;
					mNotification.flags = Notification.FLAG_AUTO_CANCEL;
					setIntent();
					manager.notify(notificationId, mNotification);
					break;
				case 0:
//					Log.i("liang", "handler 0");
					notificationView.setTextViewText(R.id.mdmview_notification_musicTime, formatData(getProgress())
							+ "/" + formatData(duration));
					notificationView.setProgressBar(R.id.mdmview_notification_musicProgress, 100, getProgress() * 100
							/ duration, false);
					mNotification.flags = Notification.FLAG_AUTO_CANCEL;
					setIntent();
					manager.notify(notificationId, mNotification);
					break;
				case 2:
//					Log.i("liang", "handler 2");
					if(mNotification!=null&&manager!=null){
					manager.cancel(notificationId);
					}
					break;
				}
			}
		};

	}

	private void initData() {
		// TODO Auto-generated method stub
		if (player == null) {
			player = new MediaPlayer();
			player.setOnCompletionListener(new OnCompletionListener() {

				@Override
				public void onCompletion(MediaPlayer mp) {
					// TODO Auto-generated method stub
					isFinish = true;
					isPlaying = false;
					Message.obtain(handler, 2, 0).sendToTarget();
				}
			});
			player.setOnErrorListener(new OnErrorListener() {

				@Override
				public boolean onError(MediaPlayer mp, int what, int extra) {
					// TODO Auto-generated method stub
					mp.reset();
					state=0;
					isLoop=false;
					isPlaying=false;
					return false;
				}
			});
		}
		notificationThread = new Thread() {
			@Override
			public void run() {
				while (isLoop) {
					while (isLoop && isPlaying) {
						Message.obtain(handler, 1, 0).sendToTarget();
						try {
							sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					synchronized (notificationThread) {
						try {
							this.wait();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			}
		};
	}

	@Override
	public int readyMusic(Context context, FileFolderInfo path) {
		// TODO Auto-generated method stub
		isLoop = true;
		this.context = context;
		this.fileinfo = path;
		Log.i("liang", path.getMusicPath());
		if (path.getMusicPath().equals(currentPath) && duration != 0 && state == 1) {
			return duration;
		}
		try {
			if (state == 0) {
				Log.i("liang", "state==0");
				initData();
				initPlayer();
				initNotification();
				state = 1;
			} else if (state == 1) {
				Log.i("liang", "state==1");
				initPlayer();
				if (notificationView != null) {
					notificationView.setTextViewText(R.id.mdmview_notification_musicName,
							fileinfo.getName());
					notificationView.setProgressBar(R.id.mdmview_notification_musicProgress, 100, 0, false);
					notificationView.setTextViewText(R.id.mdmview_notification_musicTime, formatData(0) + "/"
							+ formatData(duration));
					manager.notify(notificationId, mNotification);
					setIntent();
				}
			}

		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		}
		duration = player.getDuration();
		return duration;
	}

	private void setIntent(){
		Intent intent = new Intent(context, FileDownloadActivity.class);
		intent.putExtra(ClientConfig.FILE_FOLDER_INFO, fileinfo);
		intent.putExtra("isMusic", true);
		PendingIntent contentIntent = PendingIntent.getActivity(context, notificationId, intent,
				PendingIntent.FLAG_UPDATE_CURRENT);
		mNotification.contentIntent = contentIntent;
	}
	
	private void initPlayer() throws IllegalArgumentException, SecurityException, IllegalStateException, IOException {
		
		isPlaying = false;
		isFinish = false;
		File file=new File(fileinfo.getMusicPath());
		Log.i("liang", "musicFileIsExit:"+file.exists());
		fis=new FileInputStream(file);
		player.reset();
		player.setDataSource(fis.getFD());
		player.prepare();
		currentPath = fileinfo.getMusicPath();
		currentDuration = 0;
	}

	@SuppressWarnings("static-access")
	private void initNotification() {
		// TODO Auto-generated method stub
		mNotification = new Notification();
		mNotification.icon = R.mipmap.icon_logo_b;
//		mNotification.flags = Notification.FLAG_ONGOING_EVENT;
		mNotification.flags = Notification.FLAG_AUTO_CANCEL;
		mNotification.tickerText = "onebox-music";
		manager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
		notificationView = new RemoteViews(context.getPackageName(), R.layout.notification_musicplayer);
		notificationView.setTextViewText(R.id.mdmview_notification_musicName, fileinfo.getName());
		notificationView.setProgressBar(R.id.mdmview_notification_musicProgress, 100, 0, false);
		mNotification.contentView = notificationView;
		setIntent();
		notificationThread.start();
	}

	private String formatData(int time) {
		return new SimpleDateFormat("mm:ss").format(time);
	}

	@Override
	public void play() {
		// TODO Auto-generated method stub
		player.start();
		isPlaying = true;
		isFinish = false;
		synchronized (notificationThread) {
			notificationThread.notify();
		}

	}

	@Override
	public void pause() {
		// TODO Auto-generated method stub
		player.pause();
		isPlaying = false;
		Message.obtain(handler, 0, 0).sendToTarget();
	}

	@Override
	public int getProgress() {
		// TODO Auto-generated method stub
		if (isFinish) {
			isPlaying = false;
			return -1;
		}
		if (state == 0) {
			return 0;
		}
		currentDuration = player.getCurrentPosition();
		return currentDuration;
	}

	public void setProgress(int time) {
		player.seekTo(time);
		if (isPlaying) {
			synchronized (notificationThread) {
				notificationThread.notify();
			}
		}

	}

	@Override
	public boolean isMusicPlaying() {
		// TODO Auto-generated method stub
		return isPlaying;
	}

	@Override
	public void destory() {
		// TODO Auto-generated method stub
		Log.i("liang", "musicdestory");
		isLoop = false;
		isPlaying = false;
		state = 0;
		currentDuration = 0;
		if (notificationThread != null) {
			synchronized (notificationThread) {
				notificationThread.notify();
			}
		}
		if (player != null) {
			player.stop();
			player.reset();
		}
		if (manager != null) {
			manager.cancel(notificationId);
		}
		if(fis!=null){
			try {
				fis.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}
